home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-06 | 9.7 KB | 341 lines | [TEXT/BROW] |
- //
- // File: demo.c
- //
- // This file contains the routines that control the demo.
- //
- // 2/19/95 -- Created by Mick
- //
-
- // include files
-
- #include "global.h"
-
- #include <Palettes.h>
- #include <QDOffscreen.h>
-
- #include "demo.h"
-
- #include "main.h"
- #include "sprite.h"
-
- // defines for this file
-
- #define kMaxObjects 10 // the maximum number of objects in the demo
- #define kClipRectInset 100 // the amount to inset the clip rect
-
- // typedefs for this file
-
- typedef struct
- {
- tSpriteInfo *fSpriteInfo; // the information on the sprite for this object
- unsigned char fIsVisible; // should we draw this object
- signed long fXPos; // the x position of this object ( 16:16 fixed )
- signed long fYPos; // the y position of this object ( 16:16 fixed )
- signed long fDeltaX; // the x coord of the velocity of this object
- signed long fDeltaY; // the y coord of the velocity of this object
- } tObjectInfo;
-
- // global function declarations
-
- void startupDemo( void );
- void shutdownDemo( void );
- void demoKey( unsigned char inKey );
- void doDemoFrame( void );
-
- // global data owned by this file
-
- GWorldPtr gOffscreenBuffer; // the port and gdevice of the offscreen buffer
- PixMapHandle gOffscreenPixels; // the actual pixmap of the offscreen buffer
- Rect gOffscreenRect; // the size of the offscreen buffer
-
- // local function declarations
-
- static void moveObjects( void ); // move all the objects
- static void blitToScreen( void ); // copy data from offscreen to onscreen
- static void restoreBackground( void ); // redraw the background
-
- // static data
-
- static tObjectInfo sObjects[ kMaxObjects ]; // the data for all the objects
- static unsigned char sClippingFlag; // are we clipping
- static Rect sClipRect; // the rect that we are clipping to
-
- // functions
-
- //
- // startupDemo -
- //
- // Create and load all the buffers and data needed for the demo.
- //
-
- void startupDemo( void )
- {
- unsigned short indexCounter; // a counter to scan the object array
-
- // create the offscreen gworld
- NewGWorld( &gOffscreenBuffer, 8, &( gMainWindow->portRect ), gAppColorTable, ( GDHandle )kNil, keepLocal );
-
- // get the pixel map and rect
- gOffscreenPixels = GetGWorldPixMap( gOffscreenBuffer );
- gOffscreenRect = gMainWindow->portRect;
-
- // load the sprite
- for( indexCounter = 0; indexCounter < kMaxObjects; indexCounter++ )
- {
- // load the sprites
- sObjects[ indexCounter ].fSpriteInfo = loadSprite( kNumberOne + indexCounter );
-
- // give it a random location and velocity
- sObjects[ indexCounter ].fXPos = ( Random() & 0x00FF ) << 16;
- sObjects[ indexCounter ].fYPos = ( Random() & 0x00FF ) << 16;
- sObjects[ indexCounter ].fDeltaX = Random() << 4;
- sObjects[ indexCounter ].fDeltaY = Random() << 4;
-
- // initially, it is visible
- sObjects[ indexCounter ].fIsVisible = kTrue;
- }
-
- // determine the clip rect
- sClipRect = gOffscreenRect;
- InsetRect( &sClipRect, kClipRectInset, kClipRectInset );
-
- // set the initial flags
- sClippingFlag = kFalse;
- }
-
-
- //
- // shutdownDemo -
- //
- // Release all the memory used by the demo.
- //
-
- void shutdownDemo( void )
- {
- unsigned short indexCounter; // a counter to scan the object array
-
- // dump the sprites
- for( indexCounter = 0; indexCounter < kMaxObjects; indexCounter++ )
- {
- disposeSprite( sObjects[ indexCounter ].fSpriteInfo );
- }
-
- // dump the offscreen gworld
- DisposeGWorld( gOffscreenBuffer );
- }
-
-
- //
- // demoKey -
- //
- // Handle a key stroke -- allows the user to set options while the demo runs.
- //
-
- void demoKey( unsigned char inKey )
- {
- // depending on the key pressed
- switch( inKey )
- {
- case 'c': // turn clipping on and off
- sClippingFlag = !sClippingFlag;
- break;
- case '1': // turn this number on and off
- sObjects[ 0 ].fIsVisible = !sObjects[ 0 ].fIsVisible;
- break;
- case '2': // turn this number on and off
- sObjects[ 1 ].fIsVisible = !sObjects[ 1 ].fIsVisible;
- break;
- case '3': // turn this number on and off
- sObjects[ 2 ].fIsVisible = !sObjects[ 2 ].fIsVisible;
- break;
- case '4': // turn this number on and off
- sObjects[ 3 ].fIsVisible = !sObjects[ 3 ].fIsVisible;
- break;
- case '5': // turn this number on and off
- sObjects[ 4 ].fIsVisible = !sObjects[ 4 ].fIsVisible;
- break;
- case '6': // turn this number on and off
- sObjects[ 5 ].fIsVisible = !sObjects[ 5 ].fIsVisible;
- break;
- case '7': // turn this number on and off
- sObjects[ 6 ].fIsVisible = !sObjects[ 6 ].fIsVisible;
- break;
- case '8': // turn this number on and off
- sObjects[ 7 ].fIsVisible = !sObjects[ 7 ].fIsVisible;
- break;
- case '9': // turn this number on and off
- sObjects[ 8 ].fIsVisible = !sObjects[ 8 ].fIsVisible;
- break;
- case '0': // turn this number on and off
- sObjects[ 9 ].fIsVisible = !sObjects[ 9 ].fIsVisible;
- break;
- default: // unknown key
- SysBeep( 0 );
- break;
- }
- }
-
-
- //
- // doDemoFrame -
- //
- // Move the demo ahead one frame -- move the sprites and draw.
- //
-
- void doDemoFrame( void )
- {
- CGrafPtr oldPort; // the graf port that is in place when we are called
- GDHandle oldDevice; // the gdevice that is in place when we are called
- signed short indexCounter; // a counter to scan all the objects
- Rect clipFrame; // the rect of the frame to the clipping area
- Point drawPoint; // where to draw the sprite
-
- // save the current port and gdevice
- GetGWorld( &oldPort, &oldDevice );
-
- // set the offscreen buffer as current ( and lock the pixel map )
- SetGWorld( gOffscreenBuffer, ( GDHandle )kNil );
- LockPixels( gOffscreenPixels );
-
- // restore the background
- restoreBackground();
-
- // move the objects
- moveObjects();
-
- // setup to draw the shapes (and handle the clipping)
- if ( sClippingFlag )
- {
- clipFrame = sClipRect;
- InsetRect( &clipFrame, -1, -1 );
- FrameRect( &clipFrame );
- startSpriteDraw( &sClipRect, gOffscreenPixels );
- }
- else
- {
- startSpriteDraw( &gOffscreenRect, gOffscreenPixels );
- }
-
- // draw the sprites from back to front
- for( indexCounter = kMaxObjects - 1; indexCounter >= 0; indexCounter-- )
- {
- if ( sObjects[ indexCounter ].fIsVisible )
- {
- drawPoint.h = ( sObjects[ indexCounter ].fXPos ) >> 16;
- drawPoint.v = ( sObjects[ indexCounter ].fYPos ) >> 16;
- drawSprite( sObjects[ indexCounter ].fSpriteInfo, drawPoint );
- }
- }
-
- // shutdown the shape draw
- endSpriteDraw();
-
- // copy the buffer to the screen
- blitToScreen();
-
- // restore the current port and gdevice
- UnlockPixels( gOffscreenPixels );
- SetGWorld( oldPort, oldDevice );
- }
-
-
- //
- // moveObjects -
- //
- // Move all the objects.
- //
-
- void moveObjects( void )
- {
- unsigned short indexCounter; // a counter to scan all the objects
-
- // concider each object
- for( indexCounter = 0; indexCounter < kMaxObjects; indexCounter++ )
- {
- // apply the velocity
- sObjects[ indexCounter ].fXPos += sObjects[ indexCounter ].fDeltaX;
- sObjects[ indexCounter ].fYPos += sObjects[ indexCounter ].fDeltaY;
-
- // if the object has hit an edge, bounce it
- if( sObjects[ indexCounter ].fXPos < ( gOffscreenRect.left << 16 ) )
- {
- sObjects[ indexCounter ].fDeltaX *= -1;
- sObjects[ indexCounter ].fXPos += ( gOffscreenRect.left << 16 ) - sObjects[ indexCounter ].fXPos;
- }
- if( sObjects[ indexCounter ].fYPos < ( gOffscreenRect.top << 16 ) )
- {
- sObjects[ indexCounter ].fDeltaY *= -1;
- sObjects[ indexCounter ].fYPos += ( gOffscreenRect.top << 16 ) - sObjects[ indexCounter ].fYPos;
- }
- if( sObjects[ indexCounter ].fXPos +
- ( ( ( sObjects[ indexCounter ].fSpriteInfo )->fSpriteRect.right -
- ( sObjects[ indexCounter ].fSpriteInfo )->fSpriteRect.left ) << 16 ) >
- ( gOffscreenRect.right << 16 ) )
- {
- sObjects[ indexCounter ].fDeltaX *= -1;
- sObjects[ indexCounter ].fXPos += ( ( gOffscreenRect.right -
- ( ( sObjects[ indexCounter ].fSpriteInfo )->fSpriteRect.right -
- ( sObjects[ indexCounter ].fSpriteInfo )->fSpriteRect.left ) ) << 16 ) -
- sObjects[ indexCounter ].fXPos;
- }
- if( sObjects[ indexCounter ].fYPos +
- ( ( ( sObjects[ indexCounter ].fSpriteInfo )->fSpriteRect.bottom -
- ( sObjects[ indexCounter ].fSpriteInfo )->fSpriteRect.top ) << 16 ) >
- ( gOffscreenRect.bottom << 16 ) )
- {
- sObjects[ indexCounter ].fDeltaY *= -1;
- sObjects[ indexCounter ].fYPos += ( ( gOffscreenRect.bottom -
- ( ( sObjects[ indexCounter ].fSpriteInfo )->fSpriteRect.bottom -
- ( sObjects[ indexCounter ].fSpriteInfo )->fSpriteRect.top ) ) << 16 ) -
- sObjects[ indexCounter ].fYPos;
- }
- }
- }
-
-
- //
- // blitToScreen -
- //
- // This routine updates the screen from the offscreen buffer.
- //
-
- void blitToScreen( void )
- {
- CGrafPtr oldPort; // the graf port that is in place when we are called
- GDHandle oldDevice; // the gdevice that is in place when we are called
-
- // save the current port and gdevice
- GetGWorld( &oldPort, &oldDevice );
-
- // set the drawing environment to the screen
- SetGWorld( ( CWindowPtr )gMainWindow, GetMainDevice() );
-
- // make sure that the fore and back colors are correct to prevent colorize mode
- ForeColor( blackColor );
- BackColor( whiteColor );
-
- // Copy the screen's color table seed into the source pixmap.
- // This will minimize CopyBits' setup time.
- ( *( ( *gOffscreenPixels )->pmTable ) )->ctSeed = ( *( ( *( ( *( GetGDevice() ) )->gdPMap ) )->pmTable ) )->ctSeed;
-
- // copy the buffer to the screen
- CopyBits( ( BitMap * )( *gOffscreenPixels ), &( gMainWindow->portBits ),
- &gOffscreenRect, &( gMainWindow->portRect ),
- srcCopy, ( RgnHandle )kNil );
-
- // restore the current port and gdevice
- SetGWorld( oldPort, oldDevice );
- }
-
-
- //
- // restoreBackground -
- //
- // This routine redraws the background over changed areas.
- //
-
- void restoreBackground( void )
- {
- // erase the entire offscreen
- EraseRect( &gOffscreenRect );
- }